package com.tanhua.dubbo.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.enums.PassType;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserFreeze;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.ManageApi;
import com.tanhua.dubbo.server.api.ManagerApi;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.enums.CommentType;
import com.tanhua.dubbo.server.pojo.BaseUser;
import com.tanhua.dubbo.server.pojo.Publish;
import com.tanhua.dubbo.server.vo.*;
import com.tanhua.dubbo.server.vo.BaseUserVo;
import com.tanhua.dubbo.server.vo.PageResult;
import com.tanhua.dubbo.server.vo.UserInPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.time.Duration;


@Service
public class ManagerService {

    @Reference
    private UserLikeApi userLikeApi;

    @Reference
    private ManageApi manageApi;

    @Autowired
    private UserInfoService userInfoService;

    @Reference
    private QuanZiApi quanZiApi;

    @Reference
    private ManagerApi managerApi;

    @Autowired
    private UserFreezeService userFreezeService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /*
     *   消息撤销
     * */
    public String revocationMessage(String[] ids) {
        //修改是否通过字段状态信息
        Boolean result = manageApi.revocationMessage(ids);
        if (result) {
            return "消息审核撤销";
        } else {
            throw new BusinessException(ErrorResult.updateMsgFail());
        }
    }

    /*
     * 消息通过
     * */
    public String messagePass(String[] ids) {
        //修改是否通过字段状态信息
        Boolean result = manageApi.messagePass(ids);
        if (result) {
            return "消息审核通过";
        } else {
            throw new BusinessException(ErrorResult.updateMsgFail());
        }

    }

    //获取用户基本详细信息
    public BaseUserVo findUserInfoById(Long userId) {

        if (ObjectUtil.isEmpty(userId)) {
            return null;
        }
        //1  获取userinfo信息
        UserInfo userInfo = userInfoService.queryUserInfoByUserId(Convert.toLong(userId));


        //2 获取user表信息
        User user = userInfoService.queryUserById(userId);

        //3 获取喜欢表中的信息
        Long loveCount = userLikeApi.queryLoveCount(Convert.toLong(userId));//喜欢
        Long ofLoveCount = userLikeApi.queryFanCount(Convert.toLong(userId));//不喜欢
        Long loveEachOther = userLikeApi.queryEachLikeCount(Convert.toLong(userId));//互相喜欢
        //4 封装用户详细数据
        BaseUserVo baseUser = new BaseUserVo();
        if (ObjectUtil.isNotEmpty(userInfo)) {
            BeanUtil.copyProperties(userInfo, baseUser, "id");
            baseUser.setId(userId);
            baseUser.setSex(userInfo.getSex().toString());
            baseUser.setTags(userInfo.getTags());
            baseUser.setCreated(userInfo.getCreated().getTime());
        }
        baseUser.setMobile(user.getMobile());
        baseUser.setCountLiked(Convert.toInt(loveCount));//喜欢人数
        baseUser.setCountMatching(Convert.toInt(loveEachOther));//配对人数
        baseUser.setCountBeLiked(Convert.toInt(ofLoveCount));//被喜欢人数

        //5 封装详细信息表数据
        BaseUser baseInfo = managerApi.findBaseUserById(userId);
        if (ObjectUtil.isNotEmpty(baseInfo)) {
            baseUser.setLastActiveTime(baseInfo.getLastActiveTime());
            baseUser.setPersonalSignature(baseInfo.getPersonalSignature());
            baseUser.setUserStatus(baseInfo.getUserStatus().toString());
            baseUser.setLastLoginLocation(baseInfo.getLastLoginLocation());
        }
        return baseUser;
    }

    //用户冻结
    public String userFreeze(UserFreeze userFreeze) {
        if (ObjectUtil.isEmpty(userFreeze)) {
            return "添加失败";
        }
        //1 判断用户是否冻结
        UserFreeze newFreeze = userFreezeService.findUserFreeze(userFreeze.getUserId());
        if (ObjectUtil.isEmpty(newFreeze)) {
            //2 没有冻结 添加冻结
            int result = userFreezeService.saveFreeze(userFreeze);
            //3 添加失败
            if (result == 0) {
                return "添加失败";
            }
        } else {
            //3.1 已经有冻结 更改冻结
            Integer integer = userFreezeService.updateFreeze(userFreeze);
            if (integer == 0) {
                return "添加失败";
            }
        }

        //4 添加成功 在redis中设置冻结状态
        //4.1 判断redis当中是否有冻结状态 有则删除重新设置
        String redisKey = "USER_FREEZE_" + userFreeze.getUserId();
        //String hashKey="FREEZE_TIME";//冻结时间
        //String hashRange="FREEZE_RANGE_";//冻结范围
        //Object data = redisTemplate.opsForHash().get(redisKey, hashKey);
        Object dataRange = redisTemplate.opsForValue().get(redisKey);
        //4.2 判断冻结是否存在
        try {
            if (ObjectUtil.isNotEmpty(dataRange)) {
                redisTemplate.opsForHash().delete(redisKey);
            }
        } catch (Exception e) {

        }
        //5 添加冻结时间以及冻结范围
        if (userFreeze.getFreezingTime() == 1) {
            //存3天
            redisTemplate.opsForValue().set(redisKey, userFreeze.getFreezingRange().toString(), Duration.ofDays(3));
        } else if (userFreeze.getFreezingTime() == 2) {
            //存7天
            redisTemplate.opsForValue().set(redisKey, userFreeze.getFreezingRange().toString(), Duration.ofDays(7));
        } else if (userFreeze.getFreezingTime() == 3) {
            //永久封禁不设置时间
            redisTemplate.opsForValue().set(redisKey, userFreeze.getFreezingRange().toString());
        }
        //6 修改用户状态以及修改是否冻结过
        String status = "2";
        managerApi.updateUserStatus(status, userFreeze.getUserId());
        managerApi.updateisFreeze(status, userFreeze.getUserId());
        return "操作成功!";
    }


    /*
     *   数据的封装
     * */
    private Message getMessage(Publish publish, List<UserInfo> userInfoList) {
        Message message = new Message();
        //展示的编号设置的是id
        message.setId(StrUtil.toString(publish.getId()));
        message.setUserId(Convert.toInt(publish.getUserId()));
        //根据用户id，查询用户详细信息
        //UserInfo userInfo = userInfoService.queryUserInfoByUserId(publish.getUserId());
        if (ObjectUtil.isNotNull(userInfoList)) {
            for (UserInfo userInfo : userInfoList) {
                if (ObjectUtil.equal(userInfo.getUserId(), publish.getUserId())) {
                    //昵称
                    message.setNickname(userInfo.getNickName());
                    //头像
                    message.setUserLogo(userInfo.getLogo());
                }
            }
        } else {
            UserInfo userInfo = userInfoService.queryUserInfoByUserId(publish.getUserId());
            //昵称
            message.setNickname(userInfo.getNickName());
            //头像
            message.setUserLogo(userInfo.getLogo());
        }
        //发布日期
        message.setCreateDate(publish.getCreated());
        //正文
        message.setText(publish.getText());
        //图片
        message.setMedias(publish.getMedias());
        //审核状态
        message.setState(publish.getMessageType().toString());
        //置顶状态
        message.setTopState(publish.getTopState());
        //点赞数
        //将点赞数和存入到publish表中
        Integer likeCount = Convert.toInt(quanZiApi.queryCount(publish.getId().toString(), CommentType.LIKE));
        // quanZiApi.updatePublishLikeCount(likeCount,publish.getId());
        message.setLikeCount(likeCount);
        //评论数
        Integer commentCount = Convert.toInt(quanZiApi.queryCount(publish.getId().toString(), CommentType.COMMENT));
        //  quanZiApi.updateCommentCount(commentCount,publish.getId());
        message.setCommentCount(commentCount);
        //举报数
        message.setReportCount(0);
        //转发
        message.setForwardingCount(0);
        return message;
    }

    /*
     *   取消消息置顶
     * */
    public String untopMessage(String id) {
        //修改是否通过字段状态信息
        Boolean result = manageApi.untopMessage(id);
        if (result) {
            return "消息取消置顶";
        } else {
            throw new BusinessException(ErrorResult.untopMsgFail());
        }
    }

    /*
     *   消息详情
     * */
    public Message getMessage(String id) {
        //动态详情
        try {
            Publish publish = manageApi.getMessage(id);
            Message message = getMessage(publish, null);
            return message;
        } catch (Exception e) {
            throw new BusinessException(ErrorResult.getMessageFail());
        }

    }

    //取消冻结
    public String unfreeze(Long userId, String reasonsForThawing) {
        //1 判断是否冻结(redis)
        Boolean flag = false;
        String redisKey = "USER_FREEZE_" + userId;
        String data = redisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isNotEmpty(data)) {
            //有冻结
            flag = true;
        }
        //2 查询是否存在冻结 (数据库)
        UserFreeze userFreeze = userFreezeService.findUserFreeze(Convert.toInt(userId));
        //2.1 没有冻结删除redis的冻结 同步
        if (ObjectUtil.isEmpty(userFreeze)) {
            if (flag) {
                //删除redis的冻结
                try {
                    redisTemplate.delete(redisKey);
                } catch (Exception e) {
                }
            }
            return "没有冻结 解冻失败";
        }
        //3 有冻结 解除冻结(数据库)
        int result = userFreezeService.deleteFreeze(userId);
        if (result == 0) {
            return "解冻失败";
        }
        //3.1 解冻redis
        try {
            redisTemplate.delete(redisKey);
        } catch (Exception e) {
        }

        //4 将用户的状态修改为正常以及添加解冻原因
        managerApi.updateUserStatus("1", Convert.toInt(userId));
        managerApi.saveFreezeReason(userId, reasonsForThawing);
        return "解冻成功!";
    }

    //用户分页条件
    public PageResult queryByPage(Integer page, Integer pagesize, Long id, String nickname, String city) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pagesize);

        //1 判断查询条件是否都为空
        if (ObjectUtil.isAllEmpty(id, nickname, city)) {
            //2 查询所有的数据
            //2.1 查询所有的userinfo表
            IPage<UserInfo> userInfoList = userInfoService.findAll(page, pagesize);
            //2.2 获得所有的用户详细信息
            List<UserInPage> userInPageList = new ArrayList<>();
            for (UserInfo record : userInfoList.getRecords()) {
                UserInPage userinPage = makeUserInPage(record);
                userInPageList.add(userinPage);
            }
            //3 返回pageResult
            pageResult.setItems(userInPageList);
            pageResult.setCounts(userInPageList.size());//总记录数
            pageResult.setPages(userInPageList.size() / Convert.toInt(pagesize));//总页数
            return pageResult;
        }
        //2 判断userId是否为空 userid唯一值 直接根据userId查找
        if (ObjectUtil.isNotEmpty(id)) {
            UserInfo userInfo = userInfoService.queryUserInfoByUserId(id);
            UserInPage user = makeUserInPage(userInfo);
            //封装到对象中返回
            List<UserInPage> users = new ArrayList<>();
            users.add(user);
            pageResult.setItems(users);
            pageResult.setCounts(1);//总记录数
            pageResult.setPages(1);//总页数
            return pageResult;
        }
        //3 判断昵称是否为空
        if (StringUtils.isEmpty(nickname)) {
            String subCity = city.substring(0, 1);
            //3.1 城市必定不为空
            IPage<UserInfo> userInfoList = userInfoService.queryUserInfoByCity(subCity, page, pagesize);
            return makeResult(pageResult, userInfoList, pagesize);
        }
        //4 根据昵称返回数据
        IPage<UserInfo> userInfoList = userInfoService.queryUserInfoByNickName(nickname, page, pagesize);
        return makeResult(pageResult, userInfoList, pagesize);
    }

    //封装对象方法
    public UserInPage makeUserInPage(UserInfo userInfo) {
        UserInPage userinPage = new UserInPage();
        BaseUser baseUser = managerApi.findBaseUserById(userInfo.getUserId());

        //2.3 封装userinfo的信息
        BeanUtil.copyProperties(userInfo, userinPage);
        //2.4 封装baseuser的信息
        BeanUtil.copyProperties(baseUser, userinPage, "id");
        userinPage.setSex(userInfo.getSex().toString());
        //2.5 获取user对象 封装手机号码
        User user = userInfoService.queryUserById(userInfo.getUserId());
        if (ObjectUtil.isNotEmpty(user)) {
            userinPage.setMobile(user.getMobile());
        }
        return userinPage;
    }

    //封装对象集合方法
    public PageResult makeResult(PageResult pageResult, IPage<UserInfo> userInfoList, Integer pagesize) {
        List<UserInPage> userInPageList = new ArrayList<>();
        for (UserInfo record : userInfoList.getRecords()) {
            UserInPage userinPage = makeUserInPage(record);
            userInPageList.add(userinPage);
        }
        //3.2 返回pageResult
        pageResult.setItems(userInPageList);
        pageResult.setCounts(userInPageList.size());//总记录数
        pageResult.setPages(userInPageList.size() / Convert.toInt(pagesize));//总页数
        return pageResult;
    }

    /*
     *   消息置顶
     * */
    public String topMessage(String id) {
        //修改是否通过字段状态信息
        Boolean result = manageApi.topMessage(id);
        if (result) {
            return "消息置顶";
        } else {
            throw new BusinessException(ErrorResult.topMsgFail());
        }
    }


    /*
     *   消息拒绝
     * */
    public String rejectMessage(String[] ids) {
        //修改是否通过字段状态信息
        Boolean result = manageApi.rejectMessage(ids);
        if (result) {
            return "消息审核未通过";
        } else {
            throw new BusinessException(ErrorResult.updateMsgFail());
        }
    }


    /*
     *   消息翻页
     * */
    public PageResult pageMessage(MsgParams msgParams) {
        //获取页码
        Integer page = msgParams.getPage();
        //获取size
        Integer pageSize = msgParams.getPagesize();
        //获取排序字段
        String sortProp = msgParams.getSortProp();
        //获取排序的形式
        String sortOrder = msgParams.getSortOrder();
        //获取消息id
        String id = msgParams.getId();
        //获取开始时间
        String sd = msgParams.getSd();
        //获取结束时间
        String ed = msgParams.getEd();
        //获取用户id
        String uid = msgParams.getUid();
        //获取审核状态
        String state = msgParams.getState();
        //查询状态对应的所有的列表信息
        List<Publish> publishList = manageApi.findAllPublish(page, pageSize, sortProp, sortOrder, sd, ed, id, state, uid);
        if (publishList.size() == 0) {
            throw new BusinessException(ErrorResult.findMessageFail());
        }
        //定义前端需要的集合信息
        List<Message> messageList = new ManagedList<>();
        //获取动态表中所有的用户id
        List<Object> userId = CollUtil.getFieldValues(publishList, "userId");
        //获取用户id集合转换成long类型
        List<Long> userIdList = new ArrayList<>();
        for (Object o : userId) {
            userIdList.add(Convert.toLong(o));
        }
        //查询所有的userInf信息
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.in("user_id", userIdList);
        List<UserInfo> userInfoList = userInfoService.queryUserInfoList(wrapper);
        //将动态表中的信息分装到前端需要的message中
        for (Publish publish : publishList) {
            Message message = getMessage(publish, userInfoList);
            messageList.add(message);
        }
        //根据传入得条件对查询的数据进行 一个排序
        if (sortProp.equals("likeCount")) {
            if (sortOrder.equals("ascending")) {
                Collections.sort(messageList, (m1, m2) -> m1.getLikeCount() - m2.getLikeCount());
            } else if (sortOrder.equals("descending")) {
                Collections.sort(messageList, (m1, m2) -> m2.getLikeCount() - m1.getLikeCount());
            }
        } else if (sortProp.equals("commentCount")) {
            if (sortOrder.equals("ascending")) {
                Collections.sort(messageList, (m1, m2) -> m1.getCommentCount() - m2.getCommentCount());
            } else if (sortOrder.equals("descending")) {
                Collections.sort(messageList, (m1, m2) -> m2.getCommentCount() - m1.getCommentCount());
            }
        }else if (sortProp.equals("createDate")) {
            if (sortOrder.equals("ascending")) {
                Collections.sort(messageList, (m1, m2) -> Convert.toInt(m1.getCreateDate()) - Convert.toInt(m2.getCreateDate()));
            } else if (sortOrder.equals("descending")) {
                Collections.sort(messageList, (m1, m2) ->Convert.toInt(m2.getCreateDate()) - Convert.toInt(m1.getCreateDate()));
            }
        }
        Collections.sort(messageList, (m1, m2) -> m2.getTopState() - m1.getTopState());

        //最后封装数据
        PageResult pageResult = new PageResult();
        pageResult.setItems(messageList);
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        //状态合计
        List<Totals> totalsList = new ArrayList<>();
        Totals totals1 = new Totals();
        //总条数
        Integer allCount = manageApi.find(id, sd, ed, null, uid);
        totals1.setTitle("全部");
        //总条数的数量
        totals1.setValue(allCount);
        totals1.setCode("all");
        totalsList.add(totals1);
        //待审核的状态
        Totals totals2 = new Totals();
        totals2.setTitle("待审核");
        totals2.setCode("3");
        //待审核的数量
        Integer waitCount = manageApi.find(id, sd, ed, PassType.WAIT.getValue(), uid);
        totals2.setValue(waitCount);
        totalsList.add(totals2);
        //已通过的状态
        Totals totals3 = new Totals();
        totals3.setTitle("已通过");
        totals3.setCode("4");
        //已通过的数量
        Integer passCount = manageApi.find(id, sd, ed, PassType.PERSONPASS.getValue(), uid);
        totals3.setValue(passCount);
        totalsList.add(totals3);
        //拒绝的状态
        Totals totals4 = new Totals();
        totals4.setTitle("已拒绝");
        totals4.setCode("5");
        //胡觉得数量
        Integer refuseCount = manageApi.find(id, sd, ed, PassType.PERSONREFUSE.getValue(), uid);
        totals4.setValue(refuseCount);
        totalsList.add(totals4);
        pageResult.setTotals(totalsList);
        //如果state为null 默认查询全部
        if (ObjectUtil.isNull(state)) {
            state = "all";
        }
        switch (state) {
            case "all":
                //总条数
                pageResult.setCounts(allCount);
                //总页数
                pageResult.setPages(Convert.toInt(allCount / Convert.toDouble(pageSize)));
                break;
            case "3":
                //待审核条数
                pageResult.setCounts(waitCount);
                //待审核页数
                pageResult.setPages(Convert.toInt(waitCount / Convert.toDouble(pageSize)));
                break;
            case "4":
                //审核通过
                pageResult.setCounts(passCount);
                //审核通过页数
                pageResult.setPages(Convert.toInt(passCount / Convert.toDouble(pageSize)));
                break;
            case "5":
                //审核拒绝
                pageResult.setCounts(refuseCount);
                //审核决绝页数
                pageResult.setPages(Convert.toInt(refuseCount / Convert.toDouble(pageSize)));
                break;
        }
        pageResult.setTotals(totalsList);
        return pageResult;
    }
}
